﻿using Masuit.Tools.Security;
using System.IO;
using System.Text.RegularExpressions;

namespace SimpleX
{
    public class PwdUtils
    {
        private static string _publicKeyFullName => Path.Combine(App.BaseDirectory, "JsonConfig", "public.key");
        private static string _privateKeyFullName => Path.Combine(App.BaseDirectory, "JsonConfig", "private.key");

        private static string _publicKey;
        private static string _privateKey;

        static PwdUtils()
        {
            if (File.Exists(_publicKeyFullName))
                _publicKey = File.ReadAllText(_publicKeyFullName);
            if (File.Exists(_privateKeyFullName))
                _privateKey = File.ReadAllText(_privateKeyFullName);
        }

        public static string PublicKey => _publicKey;

        public static string DefaultPwd()
        {
            return Encrypt("123456");
        }

        public static void GenerateRsaKeys()
        {
            if (!File.Exists(_publicKeyFullName) || !File.Exists(_privateKeyFullName))
            {
                var key = Masuit.Tools.Security.RsaCrypt.GenerateRsaKeys();
                File.WriteAllText(_publicKeyFullName, key.PublicKey);
                File.WriteAllText(_privateKeyFullName, key.PrivateKey);
            }
        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="string"></param>
        /// <returns></returns>
        public static string Encrypt(string @string)
        {
            return RsaCrypt.RSAEncrypt(@string, _publicKey);
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="string"></param>
        /// <returns></returns>
        public static string Decrypt(string @string)
        {
            return RsaCrypt.RSADecrypt(@string, _privateKey);
        }

        /// <summary>
        /// 密码相似度
        /// </summary>
        /// <param name="oldPassword"></param>
        /// <param name="newPassword"></param>
        /// <returns></returns>
        public static double Similarity(string oldPassword, string newPassword)
        {
            int editDistance = LevenshteinDistance(oldPassword, newPassword);
            double similarity = 1.0 - ((double)editDistance / (double)Math.Max(oldPassword.Length, newPassword.Length));
            return similarity * 100;
        }

        public static bool IsValidPassword(string password)
        {
            string pattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^\da-zA-Z]).{6,50}$";
            return Regex.IsMatch(password, pattern);
        }

        /// <summary>
        /// 计算莱文斯坦距离算法
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <returns></returns>
        public static int LevenshteinDistance(string s1, string s2)
        {
            int[,] distance = new int[s1.Length + 1, s2.Length + 1];

            for (int i = 0; i <= s1.Length; i++)
                distance[i, 0] = i;

            for (int j = 0; j <= s2.Length; j++)
                distance[0, j] = j;

            for (int i = 1; i <= s1.Length; i++)
            {
                for (int j = 1; j <= s2.Length; j++)
                {
                    int cost = (s1[i - 1] == s2[j - 1]) ? 0 : 1;

                    distance[i, j] = Math.Min(
                        Math.Min(distance[i - 1, j] + 1, distance[i, j - 1] + 1),
                        distance[i - 1, j - 1] + cost);
                }
            }
            return distance[s1.Length, s2.Length];
        }
    }
}